#coding=utf-8

from flask.globals import _request_ctx_stack, request
from flask_appbuilder import ModelView, expose
from flask_appbuilder.models.sqla.interface import SQLAInterface
from flask_appbuilder.widgets import ListItem

from app.models import MyAppLog
from app import appbuilder, socketio, app
import datetime, html


class LogListItem(ListItem):
    template = 'widgets/list_item.html'

    def __call__(self, **kwargs):
        ctx = _request_ctx_stack.top
        jinja_env = ctx.app.jinja_env

        template = jinja_env.get_template(self.template)
        args = self.template_args.copy()
        args.update(kwargs)
        args['formatters_columns']['created'] = lambda x: datetime.datetime.fromtimestamp(x).strftime("%Y%m%d %H:%M:%S.%f")
        args['formatters_columns']['stack_info'] = lambda x: html.escape(x).replace("\n", "<br>")
        args['formatters_columns']['exc_text'] = lambda x: html.escape(x)

        args['can_add'] = False
        return template.render(args)


class LogView(ModelView):
    route_base = '/log'
    datamodel = SQLAInterface(MyAppLog)
    page_size = 500
    list_widget = LogListItem
    base_order = ('id', 'desc')

    list_columns = ['id', 'name', 'msg','levelname','levelno','pathname','filename','module','exc_text',
                    'stack_info','lineno','funcName','created','thread','threadName', 'backend'
                    #'msecs','processName','processId', 'args',
                    ]
    list_template = 'log.list.html'

    @expose("/save", methods=("POST",))
    def save(self):
        if not request.base_url.startswith(app.base_url) or request.remote_addr != '127.0.0.1':
            return ''
        # remove old logs
        self._filters.clear_filters()
        order_column, order_direction = ('id', 'asc')
        count, lst = self.datamodel.query(self._filters, order_column, order_direction, page=0, page_size=50)
        if count > 10000:
            self.datamodel.delete_all(lst)

        # save MyAppLog to db
        # request.form
        datamodel = SQLAInterface(MyAppLog, appbuilder.session)
        item = datamodel.obj()
        # init obj with the data in post form
        item.name = request.form.get("name")
        item.msg = request.form.get("msg")
        item.args = request.form.get("args")
        item.levelname = request.form.get("levelname")
        item.levelno = request.form.get("levelno")
        item.pathname = request.form.get("pathname")
        item.filename = request.form.get("filename")
        item.module = request.form.get("module")
        item.exc_text = request.form.get("exc_text")
        item.stack_info = request.form.get("stack_info")
        item.lineno = request.form.get("lineno")
        item.funcName = request.form.get("funcName")
        item.created = request.form.get("created")
        item.msecs = request.form.get("msecs")
        item.thread = request.form.get("thread")
        item.threadName = request.form.get("threadName")
        item.processName = request.form.get("processName")
        item.processId = request.form.get("process")
        item.backend = request.form.get("backend")
        # check
        if not item.is_valid():
            return 'ok'
        if datamodel.add(item):
            socketio.emit('saved', "saved", namespace='/log')
        return 'ok'


# class SerialCategoryView(ModelView):
#     datamodel = SQLAInterface(SerialPortCategory)
#     related_views = [CheckUnitView]


appbuilder.add_view(LogView, "Log", icon="fa-folder-open-o", category="Settings")
